package com.warningrc.system.struts.mapper;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.dispatcher.mapper.ActionMapping;
import org.apache.struts2.dispatcher.mapper.DefaultActionMapper;

import com.opensymphony.xwork2.config.ConfigurationManager;
import com.opensymphony.xwork2.inject.Container;
import com.opensymphony.xwork2.inject.Inject;
import com.warningrc.system.Constants;

public class RestActionMapper extends DefaultActionMapper {

	private String struts_devMode;
	private Map<String, String> restMethods;
	private RestOperations restOperations;

	public RestActionMapper() {
		restOperations = new RestOperations();
	}

	@Inject
	public void initRestOperations(Container container) {
		struts_devMode = container.getInstance(String.class, "struts.devMode");
		restOperations.setUrlPatterns(container.getInstance(String.class,
				Constants.REST_ACTION_URLPATTERN));
	}

	public ActionMapping getMapping(HttpServletRequest request,
			ConfigurationManager configManager) {
		ActionMapping mapping = super.getMapping(request, configManager);
		if (mapping == null)
			return null;
		String actionName = mapping.getName();
		if ((actionName == null) || (actionName.length() == 0)
				|| mapping.getMethod() != null
				|| actionName.lastIndexOf('/') == -1)
			return mapping;
		if (restOperations.isRestUrl(request)) {
			Map<String, String> restMethods = getRestMethods();
			if (restOperations.isPut(request))
				mapping.setMethod(restMethods
						.get(Constants.REST_ACTION_METHOD_PUT));
			else if (restOperations.isDelete(request))
				mapping.setMethod(restMethods
						.get(Constants.REST_ACTION_METHOD_DELETE));
			else if (restOperations.isGet(request)) {
				if (actionName.endsWith("/"))
					mapping.setMethod(restMethods
							.get(Constants.REST_ACTION_METHOD_INDEX));
				else
					mapping.setMethod(restMethods
							.get(Constants.REST_ACTION_METHOD_GET));
			} else if (restOperations.isPost(request))
				mapping.setMethod(restMethods
						.get(Constants.REST_ACTION_METHOD_POST));
		}
		return mapping;
	}

	public Map<String, String> getRestMethods() {
		if (restMethods == null || struts_devMode == null
				|| "true".equalsIgnoreCase(struts_devMode))
			initRestMethods(container);
		return restMethods;
	}

	@SuppressWarnings("serial")
	public void initRestMethods(Container container) {
		if (restMethods == null)
			restMethods = new HashMap<String, String>() {
				{
					put(Constants.REST_ACTION_METHOD_INDEX, "index");
					put(Constants.REST_ACTION_METHOD_GET, "view");
					put(Constants.REST_ACTION_METHOD_POST, "create");
					put(Constants.REST_ACTION_METHOD_PUT, "update");
				}

				public String put(String key, String value) {
					if (value == null)
						return null;
					return super.put(key, value);
				}
			};
		restMethods.put(Constants.REST_ACTION_METHOD_INDEX, container
				.getInstance(String.class,
						Constants.REST_ACTION_METHOD_INDEX));
		restMethods.put(Constants.REST_ACTION_METHOD_GET, container
				.getInstance(String.class,
						Constants.REST_ACTION_METHOD_GET));
		restMethods.put(Constants.REST_ACTION_METHOD_POST, container
				.getInstance(String.class,
						Constants.REST_ACTION_METHOD_POST));
		restMethods.put(Constants.REST_ACTION_METHOD_PUT, container
				.getInstance(String.class,
						Constants.REST_ACTION_METHOD_PUT));
		restMethods.put(Constants.REST_ACTION_METHOD_DELETE, container
				.getInstance(String.class,
						Constants.REST_ACTION_METHOD_DELETE));
	}

	public static void main(String[] args) {
	}
}
